@page "/blog/reactive-ui-blazorise-fluent-validation"

<Seo Canonical="/blog/reactive-ui-blazorise-fluent-validation" Title="ReactiveUI, Blazorise & FluentValidation?" Description="In this blog post guides you will learn how to implement ReactiveUI, Blazorise components & FluentValidation." ImageUrl="img/blog/2022-08-19/ReactiveUI_Blazorise_FluentValidation.png" />

<BlogPageImage Source="img/blog/2022-08-19/ReactiveUI_Blazorise_FluentValidation.png" Text="ReactiveUI, Blazorise & FluentValidation?" />

<BlogPageTitle>
    ReactiveUI, Blazorise & FluentValidation?
</BlogPageTitle>

<BlogPageSubtitle>
    Sure, why not?
</BlogPageSubtitle>

<BlogPageParagraph>
    One of the things I enjoy most in my job is making stuff that doesn't naturally work together, work together. Let's go through the reasoning behind this.
</BlogPageParagraph>

<BlogPageParagraph>
    First, I'm using Blazor (WASM) with <Anchor To="https://github.com/reactiveui/reactiveui" Title="Link to ReactiveUI">ReactiveUI</Anchor>. Why ReactiveUI? Because it means all the functionality I need can be sat in its own testable C# class. And because I hate code in markup, it's messy and makes the debugger do funny things. I'm using Blazorise because I think it's developed into the very best of the available component libraries and also because Mladen was kind enough to implement ICommand property on the <Code Tag>Button</Code> control for me a couple of years ago when I started fiddling with all this.
</BlogPageParagraph>

<BlogPageParagraph>
    <Anchor To="https://github.com/FluentValidation/FluentValidation" Title="Link to FluentValidation">FluentValidation</Anchor> because we're already using FluentValidation, the team know it and they're comfortable with it. So when I - in my tech lead capacity - blow their minds with new stuff, I like to try to keep it familiar. So let's take a practical case. Here's a RegisterModel -
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation1" />

<BlogPageParagraph>
    And a validator, why not.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation2" />

<BlogPageParagraph>
    And then you're going to need a library.  <Anchor To="https://github.com/aladotnet/BlazoriseFluentValidation" Title="Link to BlazoriseFluentValidation">BlazoriseFluentValidation</Anchor> has been around for a little while and don't let the 0.94 version on the readme page fool you, the latest on NuGet is 1.0.4. After that, two minutes of Blazorise and you've got a Registration page.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation3" />

<BlogPageParagraph>
    Which, obviously enough, gives you this
</BlogPageParagraph>

<BlogPageImageModal ImageSource="img/blog/2022-08-19/register-page.png" ImageTitle="Register page" />

<BlogPageParagraph>
    So far so hoopy. But there's a few wrinkles. The button doesn't do anything. And it's just a class, this isn't ReactiveUI. So let's remedy that with a ViewModel. But wait. If I change this to a viewmodel, my validator won't work anymore! I really struggled with this one and eventually I bit the bullet and added a RegistrationViewModelValidator. Which was basically cut&paste.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation4" />

<BlogPageParagraph>
    <Blockquote>
        Authors's note: Remind me to experiment with inheriting from the Model Validator, let's not repeat ourselves
    </Blockquote>
</BlogPageParagraph>

<BlogPageParagraph>
    I've still got the <Code>RegistrationModelValidator</Code> because obviously I need to validate at the server side too.  And then it struck me, what if I injected that validator into my ViewModel to make certain that no server call would be made if the model I was sending wasn't valid? After all, I certainly didn't want to be serialising the ViewModel and sending that over the wires, it needs functionality and stuff on it.
</BlogPageParagraph>

<BlogPageParagraph>
    The answer is, of course, obvious to all you Rx types. <Code>ObservableAsPropertyHelper&lt;T&gt;</Code> was what I needed.
</BlogPageParagraph>

<BlogPageParagraph>
    So,
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation5" />

<BlogPageParagraph>
    at the top of the class. And...
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation6" />

<BlogPageParagraph>
    with the public properties. And in the constructor, this little gem -
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation7" />

<BlogPageParagraph>
    <Strong>OAPH</Strong>s are well documented on the <Anchor To="https://www.reactiveui.net/docs/handbook/observable-as-property-helper/" Title="Link to ReactiveUI website">ReactiveUI website</Anchor>, you don't need me going over it here. Basically, it's a calculated property which updates when ever the Email or Password properties change.
</BlogPageParagraph>

<BlogPageParagraph>
    After that, I thought "well why not? Why <Text Italic>shouldn't</Text> I Rx it?"
</BlogPageParagraph>

<BlogPageParagraph>
    So I added a command. This command.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation8" />

<BlogPageParagraph>
    And I added a method
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation9" />

<BlogPageParagraph>
    Which uses an injected Refit interface to do the ugly Http stuff and also the injected <Code>NavigationManager</Code> to do some nice user navigation at the end. And then I turned the method into the command in the constructor.
</BlogPageParagraph>

<BlogPageParagraph>
    <Code>Register = ReactiveCommand.CreateFromTask(RegisterAccount);</Code>
</BlogPageParagraph>

<BlogPageParagraph>
    All very well, except I hadn't validated the outgoing model yet. I could do it the method but that lacked style, I felt. And I thought, if I make it an observable, I can do other things with that.
</BlogPageParagraph>

<BlogPageParagraph>
    So I put this line into the constructor, too.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation10" />

<BlogPageParagraph>
    Now that isValid variable is an <Code>IObservable&lt;bool&gt;</Code>. Which means I can add it to my ReactiveCommand's canExecute property. Now the command literally cannot execute unless the Validator says my calculated model is valid.
</BlogPageParagraph>

<BlogPageParagraph>
    <Code>Register = ReactiveCommand.CreateFromTask(RegisterAccount, isValid);</Code>
</BlogPageParagraph>

<BlogPageParagraph>
    Hmm. I need one more thing here. If you can't fire the command, I don't want to button to be enabled. But I can't bind Disabled to an Observable. Unless I bind to another <Strong>OAPH</Strong>. Aha!
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation11" />

<BlogPageParagraph>
    And back in the constructor, rather than create yet another observable....
</BlogPageParagraph>

<BlogPageParagraph>
    <Code>_canRegister = Register.CanExecute.ToProperty(this, x =&gt; x.CanRegister);</Code>
</BlogPageParagraph>

<BlogPageParagraph>
    We're all done in the ViewModel, we've got everything we need. So what's left?
</BlogPageParagraph>

<BlogPageParagraph>
    Ah yes, bindings in the View.  Here's the completed markup of the View.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation12" />

<BlogPageParagraph>
    So I'm binding to the ViewModel properties. I'm using Blazorise's <Code>Command</Code> property to bind directly to my ReactiveCommand. And I've even bound the <Code>Disabled</Code>property of the button to the inverse of <Code>ViewModel.CanRegister</Code>
</BlogPageParagraph>

<BlogPageParagraph>
    But there's something odd here, I've injected NavigationManager. Which isn't testable. How the hell am I going to test this?
</BlogPageParagraph>

<BlogPageParagraph>
    By creating a mock, of course. SO here's my MockNavigationManager.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation13" />

<BlogPageParagraph>
    And here, just to round everything off, is one of my working unit tests.
</BlogPageParagraph>

<BlogPageSourceBlock Code="ReactiveUIFluentValidation14" />

<BlogPageParagraph>
    Obviously you don't have to do it this way. But you can if you want to.
</BlogPageParagraph>

<BlogPageParagraph>
    Have fun out there!
</BlogPageParagraph>

<BlogPagePostInto UserName="Rich Bryant" ImageName="richbryant" PostedOn="August 19th, 2022" Read="5 min" />
